package netty.websocket;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 初始化器，channel注册后，会执行里面的初始化方法
 */
@Component
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        //获得对应的管道
        ChannelPipeline pipeline = channel.pipeline();

        //通过管道，添加handler处理器
        //请求到客户端，需要做解码，相应到客户端做编码
        pipeline.addLast("httpServerCodec",new HttpServerCodec());

        //添加对大数据流的支持
        pipeline.addLast(new ChunkedWriteHandler());

        //对httpMessage进行聚合,聚合成FullHttpRequest和FullHttpResponse
        //几乎在netty中都会使用到该handler
        pipeline.addLast(new HttpObjectAggregator(1024*64));

        //========================以上都是支持http协议相关的handler===========================================
        //=========================心跳监测==========================
        //针对客户端，如果在1分钟没有向服务端发送读写心跳，则主动断开连接
        pipeline.addLast(new IdleStateHandler(5,10,20, TimeUnit.MINUTES));
        pipeline.addLast(new HeartBeatHandler());
        //========================以下是支持websocket协议===========================================
        //websocket 服务器处理的协议，用于指定给客户端连接的时候访问路由
        //此handler会处理一些复杂的操作，如握手操作ping+pong=心跳
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        //自定义的助手类，当请求访问，返回"hello"
        pipeline.addLast(new ChatHandler(rabbitTemplate));
    }
}
